package org.fuckerfucker.todoapp_kotlin.fragments.list

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.google.android.material.snackbar.Snackbar
import org.fuckerfucker.todoapp_kotlin.R
import org.fuckerfucker.todoapp_kotlin.data.model.Todo
import org.fuckerfucker.todoapp_kotlin.data.viewmodel.TodoViewModel
import org.fuckerfucker.todoapp_kotlin.databinding.FragmentTodoListBinding
import org.fuckerfucker.todoapp_kotlin.fragments.SharedViewModel
import org.fuckerfucker.todoapp_kotlin.fragments.list.adapter.ListAdapter
import org.fuckerfucker.todoapp_kotlin.utils.hideKeyboard
import org.fuckerfucker.todoapp_kotlin.utils.observeOnce

class ListFragment : Fragment(), SearchView.OnQueryTextListener {
    private val mTodoViewModel: TodoViewModel by viewModels()
    private val mSharedViewModel: SharedViewModel by viewModels()

    // FragmentTodoListBinding ref to layout/todo_list.xml file
    private var _binding: FragmentTodoListBinding? = null

    private val binding get() = _binding!!

    private val adapter: ListAdapter by lazy { ListAdapter() }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        // data binding
        _binding = FragmentTodoListBinding.inflate(inflater, container, false)
        binding.lifecycleOwner = this
        // the xml data section
        binding.mSharedViewModel = mSharedViewModel
        
        // setup RecyclerView
        setupRecyclerView()

        // Observe LiveData
        mTodoViewModel.getAllData.observe(viewLifecycleOwner){
            data -> mSharedViewModel.checkIfDatabaseEmpty(data)
            adapter.setData(data)
            binding.recyclerView.scheduleLayoutAnimation()
        }

        hideKeyboard(requireActivity())

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        val menuHost: MenuHost = requireActivity()
        menuHost.addMenuProvider(object : MenuProvider {
            override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
                menuInflater.inflate(R.menu.list_fragment_menu, menu)

                val search = menu.findItem(R.id.menu_search)
                val searchView = search.actionView as? SearchView
                searchView?.isSubmitButtonEnabled = true
                searchView?.setOnQueryTextListener(this@ListFragment)
            }

            override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
                when (menuItem.itemId) {
                    R.id.menu_delete_all -> confirmRemoval()

                    R.id.menu_priority_high -> mTodoViewModel.sortByHighPriority.observe(viewLifecycleOwner) {
                        adapter.setData(it)
                    }

                    R.id.menu_priority_low -> mTodoViewModel.sortByLowPriority.observe(viewLifecycleOwner) {
                        adapter.setData(it)
                    }

                    android.R.id.home -> requireActivity().onBackPressedDispatcher.onBackPressed()
                }

                return true
            }
        }, viewLifecycleOwner, Lifecycle.State.RESUMED)
    
    }
    

    private fun confirmRemoval() {
        val builder = AlertDialog.Builder(requireContext())

        builder.setPositiveButton("是") {_, _ ->
            mTodoViewModel.deleteAll()
            Toast.makeText(
                requireContext(),
                "删除成功",
                Toast.LENGTH_SHORT
            ).show()
        }

        builder.setNegativeButton("否") {_, _ -> Log.d("fragments.list.todo_list.kt", "删除取消")}

        builder.setTitle("删除所有待办?")
        builder.setMessage("你确定要删除所有待办吗?")
        builder.create().show()
    }

    private fun setupRecyclerView() {
        val recyclerView = binding.recyclerView
        recyclerView.adapter = adapter
        
        recyclerView.layoutManager =
            StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
        
        // Swipe to delete
        swipeToDelete(recyclerView)
    }

    private fun swipeToDelete(recyclerView: RecyclerView) {
        val swipeToDeleteCallback = object : SwipeToDelete() {
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                val toBeDeletedItem = adapter.dataList[viewHolder.adapterPosition]
                // Delete Item
                mTodoViewModel.deleteItem(toBeDeletedItem)
                adapter.notifyItemRemoved(viewHolder.adapterPosition)
                // Restore Deleted Item
                restoreDeletedData(viewHolder.itemView, deletedItem=toBeDeletedItem)
            }
        }
        
        val itemTouchHelper = ItemTouchHelper(swipeToDeleteCallback)
        itemTouchHelper.attachToRecyclerView(recyclerView)
    }
    
    private fun restoreDeletedData(view: View, deletedItem: Todo) {
        var snackBar = Snackbar.make(
            view, "Deleted '${deletedItem.title}'",
            Snackbar.LENGTH_LONG
        )
        
        snackBar.setAction("Undo") {
            mTodoViewModel.insertData(deletedItem)
        }
        
        snackBar.show()
    }

    override fun onQueryTextSubmit(query: String?): Boolean {
        if (query != null) {
            searchThroughDatabase(query)
        }

        return true
    }

    override fun onQueryTextChange(query: String?): Boolean {
        query?.let {
            searchThroughDatabase(query)
        }
        return true
    }

    private fun searchThroughDatabase(query: String) {
        val searchQuery = "%$query"

        mTodoViewModel.searchDatabase(searchQuery).observeOnce(viewLifecycleOwner) {
            list -> list.let {
                Log.d("fragments.list.todo_list.kt", "searchThroughDatabase")
                adapter.setData(it)
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null// do not bind anymore
    }
}